package com.shfl.task.component;

import com.shfl.task.exception.ApiException;
import com.shfl.task.logic.bean.TaskJob;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Objects;

@Component
public class SchedulerComponent {

    @Resource(name = "schedulerFactory")
    private Scheduler scheduler;

    @Autowired
    private InitComponent initComponent;

    /**
     * 编辑定时任务
     *
     * @param taskJob 定时任务
     * @throws SchedulerException
     */
    public void editCron(TaskJob taskJob) throws Exception {
        JobKey jobKey = JobKey.jobKey(taskJob.getJobName(), taskJob.getJobGroup());
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        if (jobDetail == null) {
            throw new ApiException("2102");
        }

        TriggerKey triggerKey = TriggerKey.triggerKey(String.valueOf(taskJob.getId()));
        // 获取触发器
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        if (trigger == null) {
            throw new ApiException("2004");
        }
        // 任务时间一致 不做处理
        if (Objects.equals(taskJob.getJobCron(), trigger.getCronExpression())) {
            return;
        }
        // 重新构建 触发器
        trigger = trigger.getTriggerBuilder()
                .withIdentity(triggerKey)
                .withSchedule(CronScheduleBuilder.cronSchedule(taskJob.getJobCron()))
                .build();
        // 按新的trigger重新设置job执行
        scheduler.rescheduleJob(triggerKey, trigger);
    }

    public void addTask(TaskJob taskJob) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(taskJob.getJobName(), taskJob.getJobGroup());
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        // 存在名称相同的定时任务 放弃此次新增
        if (jobDetail != null) {
            throw new ApiException("2103");
        }

        TriggerKey triggerKey = TriggerKey.triggerKey(String.valueOf(taskJob.getId()));
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        // 存在名称相同的触发器 放弃此次新增
        if (trigger != null) {
            throw new ApiException("2105");
        }
        MethodInvokingJobDetailFactoryBean jobDetailFactoryBean = null;
        try {
            jobDetailFactoryBean = initComponent.intMethodInvokingJobDetailFactoryBean(taskJob);
            trigger = initComponent.intCronTriggerFactoryBean(taskJob, jobDetailFactoryBean).getObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (trigger == null) {
            return;
        }
        // 构建定时任务
        trigger = trigger.getTriggerBuilder()
                .withIdentity(triggerKey)
                .withSchedule(CronScheduleBuilder.cronSchedule(taskJob.getJobCron()))
                .build();
        // 启动该定任务
        scheduler.scheduleJob(jobDetailFactoryBean.getObject(), trigger);

    }

    public void close(TaskJob taskJob) throws Exception {
        JobKey jobKey = JobKey.jobKey(taskJob.getJobName(), taskJob.getJobGroup());
        // 删除任务
        scheduler.deleteJob(jobKey);
    }
}
